import { defineStore } from 'pinia'
import { getUserInfo, login, logout } from '@/api/user'
import router from '@/router'
import type { RouteRecordRaw } from 'vue-router'
import type { Menu } from '@/models/menu'
import type { UserInfo } from '@/models/user'

const formatMenus = (menus: Menu[], parentId = 0, rootPath: string = ''): RouteRecordRaw[] => {
  const routes: RouteRecordRaw[] = []
  menus.forEach((item: Menu) => {
    if (item.parentId === parentId) {
      const path = rootPath ? item.name + '' : '/' + item.name
      const children = formatMenus(menus, item.id, path)
      item.name &&
        routes.push({
          path,
          children,
          name: item.name,
          meta: {
            title: item.title,
            icon: item.icon,
          },
        })
    }
  })
  return routes
}

const useUserStore = defineStore('user', {
  state: () => ({
    token: localStorage.getItem('token') || '',
    userInfo: JSON.parse(localStorage.getItem('userInfo') || '{}'),
    routes: JSON.parse(localStorage.getItem('routes') || '[]'),
  }),

  actions: {
    SET_TOKEN(token: string) {
      this.token = token
      localStorage.setItem('token', token)
    },
    SET_USERINFO(userInfo: Omit<UserInfo, 'menus'>) {
      this.userInfo = userInfo
      localStorage.setItem('userInfo', JSON.stringify(userInfo))
    },
    SET_ROUTES(routes: RouteRecordRaw[]) {
      this.routes = routes
      localStorage.setItem('routes', JSON.stringify(routes))
    },
    Login({ username, password }: { username: string; password: string }) {
      return new Promise((resolve, reject) => {
        login(username, password)
          .then(async (res) => {
            if (res.data.code === 200) {
              const { token, tokenHead } = res.data.data
              this.SET_TOKEN(`${tokenHead} ${token}`)
              await this.GetUserInfo()
              resolve(res)
            } else {
              reject(res)
            }
          })
          .catch(reject)
      })
    },
    GetUserInfo() {
      return new Promise((resolve, reject) => {
        getUserInfo()
          .then((res) => {
            const { menus, ...userInfo } = res.data.data
            this.SET_USERINFO(userInfo)
            const routes = formatMenus(menus || [])
            this.SET_ROUTES(routes)
            resolve(res)
          })
          .catch(reject)
      })
    },
    Logout() {
      return new Promise((resolve, reject) => {
        logout()
          .then((res) => {
            localStorage.removeItem('token')
            localStorage.removeItem('userInfo')
            localStorage.removeItem('menus')
            this.SET_TOKEN('')
            this.SET_USERINFO({})
            router.replace('/login?redirect=' + router.currentRoute.value.fullPath)
            resolve(res)
          })
          .catch(reject)
      })
    },
  },
})

export default useUserStore
